package com.ruoyi.web.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.web.domain.BhPlans;
import com.ruoyi.web.domain.BhReport;
import com.ruoyi.web.domain.BhRiskList;
import com.ruoyi.web.domain.query.AddReportQuery;
import com.ruoyi.web.domain.query.ReportPageQuery;
import com.ruoyi.web.domain.vo.ReportPageVO;
import com.ruoyi.web.mapper.BhPlansMapper;
import com.ruoyi.web.mapper.BhReportMapper;
import com.ruoyi.web.mapper.BhRiskListMapper;
import com.ruoyi.web.service.BhReportService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class BhReportServiceImpl implements BhReportService {
    @Autowired
    private BhReportMapper baseMapper;
    @Autowired
    private BhRiskListMapper bhRiskListMapper;
    @Autowired
    private BhPlansMapper bhPlansMapper;

    /**
     * 作业报备分页查询
     *
     * @param reportPageQuery 查询参数
     * @param pageQuery       分页参数
     * @return 分页数据
     */
    @Override
    public TableDataInfo<ReportPageVO> getReportPage(ReportPageQuery reportPageQuery, PageQuery pageQuery) {
        LambdaQueryWrapper<BhReport> lqw = buildQueryWrapper(reportPageQuery);
        Page<ReportPageVO> result;
        if (reportPageQuery.getAllFlag() != null && reportPageQuery.getAllFlag() == 1) {
            result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        } else {
            result = baseMapper.getReportPage(pageQuery.build(), lqw);
        }
        List<ReportPageVO> reportPageList = result.getRecords();
        if (CollectionUtils.isNotEmpty(reportPageList)) {
            reportPageList.forEach(x -> {
                List<String> ids = com.ruoyi.common.utils.StringUtils.str2List(x.getProjectName(), "[|]", true, true);
                List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().in(CollectionUtils.isNotEmpty(ids), BhRiskList::getId, ids).orderByAsc(BhRiskList::getId));
                x.setProjectName(bhRiskLists.stream().map(BhRiskList::getName).collect(Collectors.joining("|")));
            });
        }
        return TableDataInfo.build(result);
    }

    // 组装分页查询条件
    private LambdaQueryWrapper<BhReport> buildQueryWrapper(ReportPageQuery reportPageQuery) {
        LambdaQueryWrapper<BhReport> lqw = Wrappers.lambdaQuery();
        lqw.eq(BhReport::getDelFlag, 0);
        lqw.eq(BhReport::getInspectType, 1);
        lqw.like(StringUtils.isNotBlank(reportPageQuery.getConstructionOrganization()), BhReport::getConstructionOrganization, reportPageQuery.getConstructionOrganization());
        lqw.like(StringUtils.isNotBlank(reportPageQuery.getWellNo()), BhReport::getWellNo, reportPageQuery.getWellNo());
        lqw.like(StringUtils.isNotBlank(reportPageQuery.getWellType()), BhReport::getWellType, reportPageQuery.getWellType());
        // 处理作业项目查询条件
        String projectName = reportPageQuery.getProjectName();
        if (StringUtils.isNotBlank(projectName)) {
            List<BhRiskList> bhRiskLists = bhRiskListMapper.selectList(new LambdaQueryWrapper<BhRiskList>().eq(BhRiskList::getDelFlag, 0).like(BhRiskList::getName, projectName).orderByAsc(BhRiskList::getId));
            if (CollectionUtils.isNotEmpty(bhRiskLists)) {
                lqw.and(i -> {
                    bhRiskLists.forEach(x -> {
                        i.or().apply("find_in_set({0},REPLACE(project_name, '|', ','))", x.getId());
                    });
                });
            }
        }
        String date = reportPageQuery.getWorkStartTime();
        if (StringUtils.isNotBlank(date)) {
            DateTime start = DateUtil.beginOfDay(DateUtil.parseDate(date));
            DateTime end = DateUtil.endOfDay(DateUtil.parseDate(date));
            lqw.ge(BhReport::getWorkStartTime, start);
            lqw.le(BhReport::getWorkStartTime, end);
        }
        lqw.orderByDesc(BhReport::getFillTime);
        return lqw;
    }

    /**
     * 新增作业报备
     *
     * @param addReportQuery 新增参数
     * @return 返回
     */
    @Override
    public R<Void> addReport(AddReportQuery addReportQuery) {
        BhReport addParam = new BhReport();
        BeanUtils.copyProperties(addReportQuery, addParam);
        addParam.setDelFlag(0);     // 0-未删除
        addParam.setStatus("0");    // 0-正常 1-关闭
        addParam.setInspectType(1); // 1-正常 2-临时
        addParam.setCreateTime(new Date());
        // 创建人
        LoginUser loginUser = LoginHelper.getLoginUser();
        addParam.setCreatedBy(String.valueOf(loginUser.getUserId()));
        // 施工单位
        addParam.setConstructionOrganization(loginUser.getDeptName());
        addParam.setCoId(loginUser.getDeptId());
        if (baseMapper.insert(addParam) > 0) {
            return R.ok();
        }
        return R.fail();
    }

    /**
     * 逻辑删除作业报备数据
     *
     * @param id 作业报备id
     * @return 返回
     */
    @Override
    public R<Void> delReport(Integer id) {
        // 判断是否被计划引用了
        boolean flag = true;
        List<BhPlans> bhPlans = bhPlansMapper.selectList(new LambdaQueryWrapper<BhPlans>().eq(BhPlans::getDelFlag, 0).eq(BhPlans::getTopId, 0));
        if (CollectionUtils.isNotEmpty(bhPlans)) {
            for (BhPlans bhPlan : bhPlans) {
                String reportIds = bhPlan.getReportId();
                List<String> reportIdList = com.ruoyi.common.utils.StringUtils.str2List(reportIds, "[|]", true, true);
                if (CollectionUtils.isNotEmpty(reportIdList)) {
                    for (String reportId : reportIdList) {
                        if (id == Integer.valueOf(reportId)) {
                            flag = false;
                            break;
                        }
                    }
                }
            }
        }
        if (flag) {
            if (baseMapper.delReport(id) <= 0) {
                return R.fail("删除作业报备失败！");
            } else {
                return R.ok();
            }
        } else {
            return R.fail("该报备已被计划引用，无法删除！");
        }
    }

    /**
     * 编辑作业报备数据
     *
     * @param addReportQuery 修改参数
     * @return 返回
     */
    @Override
    public R<Void> modReport(AddReportQuery addReportQuery) {
        BhReport upParam = new BhReport();
        BeanUtils.copyProperties(addReportQuery, upParam);
        upParam.setUpdatedBy(String.valueOf(LoginHelper.getUserId()));
        upParam.setUpdatedTime(new Date());
        if (baseMapper.updateById(upParam) > 0) {
            return R.ok();
        }
        return R.fail();
    }

    /**
     * 导出作业报备数据
     *
     * @param out             输出流
     * @param reportPageQuery 导出参数
     * @param pageQuery       分页参数
     */
    @Override
    public void exportExcel(OutputStream out, ReportPageQuery reportPageQuery, PageQuery pageQuery) {
        TableDataInfo<ReportPageVO> tableDataInfo = getReportPage(reportPageQuery, pageQuery);
        if (!Objects.isNull(tableDataInfo)) {
            List<ReportPageVO> exportData = tableDataInfo.getData();
            // 生成excel
            try (ExcelWriter excelWriter = EasyExcelFactory.write(out).build()) {
                WriteSheet dealerSheet = EasyExcelFactory.writerSheet(0, "作业报备信息").head(ReportPageVO.class).build();
                excelWriter.write(exportData, dealerSheet);
            }
        }
    }

    /**
     * 获取作业报备详情
     *
     * @param id 作业报备id
     * @return 返回
     */
    @Override
    public R<ReportPageVO> getReportDetail(Integer id) {
        ReportPageVO reportPageVO = baseMapper.selectVoById(id);
        return R.ok(reportPageVO);
    }
}
